package com.kexio.dynamic.datasource.service;

import javax.sql.DataSource;
import java.util.Map;
import java.util.Set;

/**
 * 动态数据源管理服务接口
 * 
 * 提供数据源的动态添加、删除和管理功能
 * 
 * @author Kexio
 * @since 1.0.0
 */
public interface DynamicDataSourceService {

    /**
     * 添加数据源
     * 
     * @param dsName     数据源名称
     * @param dataSource 数据源实例
     */
    void addDataSource(String dsName, DataSource dataSource);

    /**
     * 添加数据源（通过配置属性）
     * 
     * @param dsName   数据源名称
     * @param property 数据源配置属性
     */
    void addDataSource(String dsName, DataSourceProperty property);

    /**
     * 移除数据源
     * 
     * @param dsName 数据源名称
     * @return 是否移除成功
     */
    boolean removeDataSource(String dsName);

    /**
     * 获取所有数据源名称
     * 
     * @return 数据源名称集合
     */
    Set<String> getCurrentDataSources();

    /**
     * 获取数据源实例
     * 
     * @param dsName 数据源名称
     * @return 数据源实例
     */
    DataSource getDataSource(String dsName);

    /**
     * 检查数据源是否存在
     * 
     * @param dsName 数据源名称
     * @return 是否存在
     */
    boolean exists(String dsName);

    /**
     * 切换到指定数据源
     * 
     * @param dsName 数据源名称
     */
    void switchToDataSource(String dsName);

    /**
     * 获取当前使用的数据源名称
     * 
     * @return 当前数据源名称
     */
    String getCurrentDataSource();

    /**
     * 测试数据源连接
     * 
     * @param dsName 数据源名称
     * @return 连接是否正常
     */
    boolean testConnection(String dsName);

    /**
     * 获取数据源连接池信息
     * 
     * @param dsName 数据源名称
     * @return 连接池信息
     */
    DataSourceInfo getDataSourceInfo(String dsName);

    /**
     * 刷新数据源
     * 重新加载配置并更新数据源
     * 
     * @param dsName 数据源名称
     */
    void refreshDataSource(String dsName);

    /**
     * 刷新所有数据源
     */
    void refreshAllDataSources();

    /**
     * 关闭数据源
     * 
     * @param dsName 数据源名称
     */
    void closeDataSource(String dsName);

    /**
     * 关闭所有数据源
     */
    void closeAllDataSources();

    /**
     * 获取数据源统计信息
     * 
     * @return 数据源统计信息映射
     */
    Map<String, DataSourceStats> getDataSourceStats();

    /**
     * 设置数据源权重（用于负载均衡）
     * 
     * @param dsName 数据源名称
     * @param weight 权重值
     */
    void setDataSourceWeight(String dsName, int weight);

    /**
     * 启用/禁用数据源
     * 
     * @param dsName  数据源名称
     * @param enabled 是否启用
     */
    void toggleDataSource(String dsName, boolean enabled);

    /**
     * 批量添加数据源
     * 
     * @param dataSources 数据源映射
     */
    void addDataSources(Map<String, DataSource> dataSources);

    /**
     * 数据源配置属性
     */
    class DataSourceProperty {
        private String url;
        private String username;
        private String password;
        private String driverClassName;
        private Integer initialSize;
        private Integer maxActive;
        private Integer minIdle;
        private Long maxWait;
        private String validationQuery;
        private Boolean testOnBorrow;
        private Boolean testOnReturn;
        private Boolean testWhileIdle;
        private Map<String, Object> properties;

        // Getters and Setters
        public String getUrl() { return url; }
        public void setUrl(String url) { this.url = url; }
        
        public String getUsername() { return username; }
        public void setUsername(String username) { this.username = username; }
        
        public String getPassword() { return password; }
        public void setPassword(String password) { this.password = password; }
        
        public String getDriverClassName() { return driverClassName; }
        public void setDriverClassName(String driverClassName) { this.driverClassName = driverClassName; }
        
        public Integer getInitialSize() { return initialSize; }
        public void setInitialSize(Integer initialSize) { this.initialSize = initialSize; }
        
        public Integer getMaxActive() { return maxActive; }
        public void setMaxActive(Integer maxActive) { this.maxActive = maxActive; }
        
        public Integer getMinIdle() { return minIdle; }
        public void setMinIdle(Integer minIdle) { this.minIdle = minIdle; }
        
        public Long getMaxWait() { return maxWait; }
        public void setMaxWait(Long maxWait) { this.maxWait = maxWait; }
        
        public String getValidationQuery() { return validationQuery; }
        public void setValidationQuery(String validationQuery) { this.validationQuery = validationQuery; }
        
        public Boolean getTestOnBorrow() { return testOnBorrow; }
        public void setTestOnBorrow(Boolean testOnBorrow) { this.testOnBorrow = testOnBorrow; }
        
        public Boolean getTestOnReturn() { return testOnReturn; }
        public void setTestOnReturn(Boolean testOnReturn) { this.testOnReturn = testOnReturn; }
        
        public Boolean getTestWhileIdle() { return testWhileIdle; }
        public void setTestWhileIdle(Boolean testWhileIdle) { this.testWhileIdle = testWhileIdle; }
        
        public Map<String, Object> getProperties() { return properties; }
        public void setProperties(Map<String, Object> properties) { this.properties = properties; }
    }

    /**
     * 数据源信息
     */
    class DataSourceInfo {
        private String name;
        private String url;
        private String driverClassName;
        private int activeConnections;
        private int idleConnections;
        private int maxConnections;
        private boolean enabled;
        private long createTime;
        private long lastActiveTime;

        // Getters and Setters
        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
        
        public String getUrl() { return url; }
        public void setUrl(String url) { this.url = url; }
        
        public String getDriverClassName() { return driverClassName; }
        public void setDriverClassName(String driverClassName) { this.driverClassName = driverClassName; }
        
        public int getActiveConnections() { return activeConnections; }
        public void setActiveConnections(int activeConnections) { this.activeConnections = activeConnections; }
        
        public int getIdleConnections() { return idleConnections; }
        public void setIdleConnections(int idleConnections) { this.idleConnections = idleConnections; }
        
        public int getMaxConnections() { return maxConnections; }
        public void setMaxConnections(int maxConnections) { this.maxConnections = maxConnections; }
        
        public boolean isEnabled() { return enabled; }
        public void setEnabled(boolean enabled) { this.enabled = enabled; }
        
        public long getCreateTime() { return createTime; }
        public void setCreateTime(long createTime) { this.createTime = createTime; }
        
        public long getLastActiveTime() { return lastActiveTime; }
        public void setLastActiveTime(long lastActiveTime) { this.lastActiveTime = lastActiveTime; }
    }

    /**
     * 数据源统计信息
     */
    class DataSourceStats {
        private String name;
        private long totalConnections;
        private long successConnections;
        private long failedConnections;
        private double avgResponseTime;
        private long lastUsedTime;
        private int weight;

        // Getters and Setters
        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
        
        public long getTotalConnections() { return totalConnections; }
        public void setTotalConnections(long totalConnections) { this.totalConnections = totalConnections; }
        
        public long getSuccessConnections() { return successConnections; }
        public void setSuccessConnections(long successConnections) { this.successConnections = successConnections; }
        
        public long getFailedConnections() { return failedConnections; }
        public void setFailedConnections(long failedConnections) { this.failedConnections = failedConnections; }
        
        public double getAvgResponseTime() { return avgResponseTime; }
        public void setAvgResponseTime(double avgResponseTime) { this.avgResponseTime = avgResponseTime; }
        
        public long getLastUsedTime() { return lastUsedTime; }
        public void setLastUsedTime(long lastUsedTime) { this.lastUsedTime = lastUsedTime; }
        
        public int getWeight() { return weight; }
        public void setWeight(int weight) { this.weight = weight; }
    }
}
